module Alu (

	input      [31:0]   a,
	input      [31:0]   b,
	input       [2:0]   op,
	output     [31:0]   aluout,
	input       [0:0]   unsig,
	output      [0:0]   compout,
	output      [0:0]   overflow

    );

	reg [31:0] c;
	reg [0:0] over;
	reg [0:0] comp;

	assign aluout = c;
	assign overflow = over;
	assign compout = comp;

    wire       [31:0]   sum;
    wire       [31:0]   diff;

    assign sum = (a + b);
    assign diff = (a - b);


	always @(a or b or op or unsig) begin

        // Operations
        case (op)

            3'b000: begin
                c <= (a & b);
            end

            3'b001: begin
                c <= (a | b);
            end

            3'b010: begin
                c <= (a + b);
            end

            3'b100: begin
                c <= ~(a | b);
            end

            3'b101: begin
                c <= (a ^ b);
            end

			3'b110: begin
				c <= (a - b);
			end

			default: begin
			end

        endcase

        // Comparison and overflow
		if (unsig == 1'b0) begin

            // If a is positive and b is negative, a > b
            if (a[31] == 1'b0 && b[31] == 1'b1) begin

                comp <= 1'b0;

                if ((op == 3'b110) && (diff[31] == 1'b1)) begin
                    over <= 1'b1;
                end else begin
                    over <= 1'b0;
                end

            end
        
			// If a is negative and b is positive, b > a
			if (a[31] == 1'b1 && b[31] == 1'b0) begin
				
                comp <= 1'b1;

                if ((op == 3'b110) && (diff[31] == 1'b0)) begin
                    over <= 1'b1;
                end else begin
                    over <= 1'b0;
                end

            end

			// If both a and b are positive, compare
			if (a[31] == 1'b0 && b[31] == 1'b0) begin

				if (a < b) begin
					comp <= 1'b1;
                end else begin
                    comp <= 1'b0;
                end

                if ((op == 3'b010) && (sum[31] == 1'b1)) begin
                    over <= 1'b1;
                end else begin
                    over <= 1'b0;
                end

			end

            // If both are negative, compare
			if (a[31] == 1'b1 && b[31] == 1'b1) begin

				if (~a > ~b) begin
                    comp <= 1'b1;
                end else begin
                    comp <= 1'b0;
                end

                if ((op == 3'b010) && (sum[31] == 1'b0)) begin
                    over <= 1'b1;
                end else begin
                    over <= 1'b0;
                end

			end

        end else begin

            over <= 1'b0;

            if (a < b) begin
                comp <= 1'b1;
            end else begin
                comp <= 1'b0;
            end

        end

    end
    
endmodule
